package org.concordia.wsdl.helper;

import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.concordia.wsdl.model.WebService;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class WebServiceWrapper {

	// contains objects of Service
	//WebService[] Services;
	public List<WebService> services = new LinkedList<WebService>();

	// contains DOM representation of one WSDL file at a moment
	Document dom;

	// contains info file objects of the WSDL files
	File[] wsfiles;

	public void doParse(String dataPath) {

		// stores the WSDL filenames and paths as objects
		// in WSfiles
		getFilenames(dataPath);

		// Creates a service object for each WSDL file in
		// Services array.
		//Services = new WebService[WSfiles.length];

		for (int i = 0; i < wsfiles.length; i++) {

			if (wsfiles[i].getName().endsWith(".wsdl")) {
				// parse the xml file i and get the dom object
				parseXmlFile(i);

				// get every message element of file i and create
				// a Service object for each one
				parseDocument(i);

			}
		}
		
		printServices();
		
	}

	public void getFilenames(String path) {
		File dir = new File(path);

		// The list of files can be retrieved as File objects
		wsfiles = dir.listFiles();
	}

	private void parseXmlFile(int no) {

		// get the factory
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

		try {

			// Using factory, get an instance of document
			// builder
			DocumentBuilder db = dbf.newDocumentBuilder();

			// parse using builder to get DOM representation
			// of the XML file
			dom = db.parse(wsfiles[no]);

		} catch (ParserConfigurationException pce) {
			pce.printStackTrace();
		} catch (SAXException se) {
			se.printStackTrace();
		} catch (IOException ioe) {
			ioe.printStackTrace();
		}
	}

	private void parseDocument(int no) {

		// get the root elememt
		Element docEle = dom.getDocumentElement();

		// get a nodelist of <message> elements
		NodeList nl = docEle.getElementsByTagName("message");

		if (nl != null && nl.getLength() > 0) {

			// get the service object and store it in
			// Services array
			services.add(getService(nl));

		}
	}

	private WebService getService(NodeList messageNL) {

		// create the new Service
		WebService s = new WebService();

		Element el;

		// get the RequestMessage element
		el = (Element) messageNL.item(0);

		// get and set the web service name in Service object
		s.setName(el.getAttribute("name").replace("Service", "").replace(
				"_Request", ""));

		// get a nodelist of <Part> elements of the request
		// message
		NodeList nl1 = el.getElementsByTagName("part");

		if (nl1 != null && nl1.getLength() > 0) {

			// get the name of inputs of the web service
			for (int i = 0; i < nl1.getLength(); i++) {
				el = (Element) nl1.item(i);

				// add input of the web service to Service
				// object
				// s.addInput(el.getAttribute("name"));
				s.addInput(el.getAttribute("name").replaceAll("WSCC:", ""));
			}
		}
		// get the RsponseMessage element
		el = (Element) messageNL.item(1);

		// get a nodelist of <Part> elements of the response
		// message
		nl1 = el.getElementsByTagName("part");

		if (nl1 != null && nl1.getLength() > 0) {

			// get the name of outputs of the web service
			for (int i = 0; i < nl1.getLength(); i++) {
				el = (Element) nl1.item(i);

				// add outputs of the web service to Service
				// object
				s.addOutput(el.getAttribute("name").replaceAll("WSCC:", ""));
			}
		}
		return s;
	}
	
	public void printServices(){
		
		for(WebService ws : services){
			System.out.print("Service Name: ");
			System.out.println(ws.getName() + "\n");

			System.out.println("Inputs:");
			for (int i = 0; i < ws.getInputs().size(); i++) {
				System.out.println(ws.getInputs().toArray()[i]);
			}

			System.out.println("\nOutputs:");
			for (int i = 0; i < ws.getOutputs().size(); i++) {
				System.out.println(ws.getOutputs().toArray()[i]);
			}
			System.out.println("\n");
		}
	}

	public void printService(int no) {
		// print service name, inputs and outputs by number

		System.out.print("Service Name: ");
		System.out.println(services.get(no).getName() + "\n");

		System.out.println("Inputs:");
		for (int i = 0; i < services.get(no).getInputs().size(); i++) {
			System.out.println(services.get(no).getInputs().toArray()[i]);
		}

		System.out.println("\nOutputs:");
		for (int i = 0; i < services.get(no).getOutputs().size(); i++) {
			System.out.println(services.get(no).getOutputs().toArray()[i]);
		}
		System.out.println("\n");
	}


}
